<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <input type="file" name="" id="input">
    <button id="btn">上传</button>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.7.5/axios.js"></script>
    <script>
        const input = document.getElementById('input');
        const btn = document.getElementById('btn');
        let fileObj = null
        input.addEventListener('change', handleFileChange);
        btn.addEventListener('click', handleUpload)

        function handleFileChange(e) {//监听change事件,获取文件对象
            // console.log(event.target.files);
            const [file] = event.target.files;
            fileObj = file;
        }
        function handleUpload() {//点击按钮上传文件到服务器
            if (!fileObj) return;
            const chunkList = createChunk(fileObj);
            // console.log(chunkList);
            const chunks = chunkList.map(({ file }, index) => {//创建切片对象
                return {
                    file,
                    size: file.size,
                    percent: 0,
                    index,
                    chunkName: `${fileObj.name}-${index}`,
                    fileName: fileObj.name,
                }
            });
            // 发请求
            uploadChunks(chunks);

        }
        //切片
        function createChunk(file, size = 5 * 1024 * 1024) {
            const chunkList = [];
            let cur = 0;
            while (cur < file.size) {
                chunkList.push({
                    file: file.slice(cur, cur + size),
                })
                cur += size;
            }
            return chunkList;
        }
        // 发请求到后端
        function uploadChunks(chunks) {
            console.log(chunks); //这个数组中的元素是对象，对象中有blob类型的文件对象，后端无法识别,所以需要转换成formData对象
            const formChunks = chunks.map(({ file, fileName, index, chunkName }) => {
                const formData = new FormData();
                formData.append('file', file);
                formData.append('fileName', fileName);
                formData.append('chunkName', chunkName);
                return { formData, index }
            })
            console.log(formChunks); // 后端能识别的类型
            //发请求
            const requestList = formChunks.map(({ formData, index }) => {//一个一个片段发
                return axios.post('http://localhost:3000/upload', formData, () => {
                    console.log(index + ' 上传成功');
                })
                    .then(res => {
                    })
            })
            Promise.all(requestList).then(() => {
                console.log('全部上传成功');
                mergeChunks();
            })
        }
        // 合并请求的信号
        function mergeChunks(size = 5 * 1024 * 1024) {
            axios.post('http://localhost:3000/merge', {
                fileName: fileObj.name,
                size
            })
                .then(res => {
                    console.log(fileObj.name + '合并成功');
                })
        }
    </script>
</body>

</html>